#include "../include/N_arytree.h"
//bstInsertNode(struct bstNode **rootNode,fd *data);
//bstDeleteNode(struct bstNode **rootNode,char* fullpath);
//hashInsert(struct HashTable *hash, fd data);
//hashDelete(struct HashTable *hash,fd data);
//This function extract backslashes at the end of given path
char* extrctslash(char* s)
{
int j,i=1,k,cnt=0;
while(s[strlen(s)-i++]=='/')
{	
	
	cnt++;
	if(cnt==strlen(s))
	return "/";
}
k=strlen(s)-cnt;
char*src;
src=(char*)malloc(sizeof(char)*k);
for(j=0;j<k;j++)
{
src[j]=s[j];
}
printf("%s",src);
s=src;
return s;

}


//this function modifies fileDescriptors of source sub tree
void modify_fd_rec(t_node** root,t_node *t,char *source,char *dest)
{	
	t_node *current;
	current = *root;
	int i,j;
    	if(t!=NULL && t->is_deleted!=1)
	{  	int cnt=0;
		fd* f = t->data;
		char **tokens=NULL;
		char **tokend=NULL;
		char **tokenc=NULL;
		char*g=NULL;
		g=dest;
		int c,s,d;
		c=generate_tokens(&tokenc,f->path,'/');
		s=generate_tokens(&tokens,source,'/');
		d=generate_tokens(&tokend,dest,'/');
		
	for(i=s-1;i<c;i++)
			{	
				cnt+=strlen(tokenc[i])+1;
				
				
			
			}
	//changing the path field of node(file/folder)
	char *buffer = malloc (strlen(dest) + cnt);
	strcat(buffer,dest);

	for(i=s-1;i<c;i++)
			{	
				if(buffer[strlen(buffer)-1]!='/')
				strcat(buffer,"/");
				strcat(buffer,tokenc[i]);
				
				
			}
	char*fullpath;
	fullpath=(char*)malloc(sizeof(char)*(strlen(f->path)+strlen(f->file_name)+1));
	strcpy(fullpath,f->path);
	strcat(fullpath,"/");
	strcpy(fullpath,f->file_name);
	


	hashDelete(hash,*f);
	bstDeleteNode(&root,fullpath);
	strcpy(f->path,buffer);

	insert_node(root,f);
	
	bstInsertNode(&root,f);
	hashInsert(hash,*f);

	
	
	t->is_deleted=1;
	}
   	
  	 if(t->right_siblings!=NULL)
    		modify_fd_rec(root,t->right_siblings,source,dest);
 	 if(t->left_child!=NULL)
  	        modify_fd_rec(root,t->left_child,source,dest);
 	
}

//this function modifies fileDescriptors of source folder
void modify_fd(t_node** root,t_node *t,char *source,char *dest)
{	
	t_node *current;
	current = *root;
	int i,j;
    	if(t!=NULL && t->is_deleted!=1)
	{  	int cnt=0;
		fd* f = t->data;
		char **tokens=NULL;
		char **tokend=NULL;
		char **tokenc=NULL;
		char*g=NULL;
		g=dest;
		int c,s,d;
		c=generate_tokens(&tokenc,f->path,'/');
		
		s=generate_tokens(&tokens,source,'/');

		d=generate_tokens(&tokend,dest,'/');
		
	for(i=s;i<c;i++)
			{	
				cnt+=strlen(tokenc[i])+1;
				
				
			
			}
	char *buffer = malloc (strlen(dest) + cnt);
	//changing the path field of node(file/folder)
	strcat(buffer,dest);

	for(i=s;i<c;i++)
			{	
				if(buffer[strlen(buffer)-1]!='/')
				strcat(buffer,"/");
				strcat(buffer,tokenc[i]);
				
				
			}

	char*fullpath;
	fullpath=(char*)malloc(sizeof(char)*(strlen(f->path)+strlen(f->file_name)+1));
	strcpy(fullpath,f->path);
	strcat(fullpath,"/");
	strcpy(fullpath,f->file_name);
	


	hashDelete(hash,*f);
	bstDeleteNode(&root,fullpath);
	strcpy(f->path,buffer);

	insert_node(root,f);
	
	bstInsertNode(&root,f);
	hashInsert(hash,*f);

	
	
	t->is_deleted=1;
	}
   	
  	
 	
}

int move_dir(t_node** root,char *source,char *dest)
{

	printf(" src-%s  dest-%s",source,dest);
	t_node *current,*par_of_curr,*par_of_dest;
	t_node *d,*stemp,*dtemp,*temp,*temp1;
	char **tokens=NULL;
	int cnt=1,count,i,flag=1,flag1=1;
        
   	
	int l=strlen(source),k,n=0;
	int m=strlen(dest);
	
	
	count=generate_tokens(&tokens,source,'/');
	
	//todo-extract slash at last of src n dest
	
   
	i = 0;
	current = *root;
	
	//Traversing source directory for validation

	while(current != NULL)
	{
		if(current->is_deleted == 0 && strcmp(current->data->file_name,tokens[i]) == 0 && current->data->fileType=='D')
		{	printf("/n %c",current->data->fileType);
			i++;
			if(i == count)
				break;
			par_of_curr=current;
			current = current->left_child;
			
		}
		//Goto right siblings
		else if(current->right_siblings != NULL)
		{
			current = current->right_siblings;
		}
		else
		{
			flag =0;
			break;
		}
	}
	//checking if source is file not folder
	if(i==count-1)
	{
			temp=par_of_curr->left_child;
	
			while(temp!=NULL)
			{
				if(temp->is_deleted == 0 && strcmp(temp->data->file_name,tokens[count-1]) == 0 && temp->data->fileType!='D')
				{
				//#define ERR_VFS_MOVEDIR_04 "SOURCE_CANNOT_BE_FILE"
				return 1;			}
				
				else 
				temp = temp->right_siblings;

			}	
	}
	//Invalid position of source
	if(flag == 0 || current == NULL)
	{
		//#define ERR_VFS_MOVEDIR_01 "CANNOT_FIND_SPECIFIED_SOURCEDIR"
		return 2;
	}
	
	
	
	count=generate_tokens(&tokens,dest,'/');
	
	
	i = 0;
	d= *root;

	//Traversing destination directory for validation
	while(d != NULL)
	{
		if(d->is_deleted == 0 && strcmp(d->data->file_name,tokens[i]) == 0 && d->data->fileType=='D')
		{
			i++;
			if(i == count)
				break;
			par_of_dest=d;
			d = d->left_child;
			
		}
		//Goto right siblings
		else if(d->right_siblings != NULL)
		{
			d = d->right_siblings;
		}
		else
		{
			flag =0;
			break;
		}
	}
	//checking if destination is file not folder
	if(i==count-1)
	{
			temp=par_of_dest->left_child;
	
			while(temp!=NULL)
			{
				if(temp->is_deleted == 0 && strcmp(temp->data->file_name,tokens[count-1]) == 0 && temp->data->fileType!='D')
				{
				//#define ERR_VFS_MOVEDIR_07 "DESTINATION_CANNOT_BE_FILE"
				return 3;			}
				
				else 
				temp = temp->right_siblings;



			}	
	}
	//Invalid position of destination
	if(flag == 0 || d == NULL)
	{
		//#define ERR_VFS_MOVEDIR_02 "CANNOT_FIND_SPECIFIED_DESTINATIONDIR" 
		
		return 4;
	}
	if(l<m)
	{
	for(k=0;k<l;k++)
	{	if(source[k]==dest[k])
		n++;
			
	}
	if(n==l)
	{	//#define ERR_VFS_MOVEDIR_06 "CANNOT_MOVE_PARENT_TO_CHILD_DIR"
		return 5;
		
	}
	}
		stemp=current;
		dtemp=d->left_child;
			while(dtemp!=NULL)
			{
			if(strcmp(dtemp->data->file_name,stemp->data->file_name)==0 && dtemp->data->fileType==stemp->data->fileType)
			    {
				//#define ERR_VFS_MOVEDIR_05 "DESTINATION_ALREADY_HAVE_SOURCE_DIR"
				return 6;
			    }
			dtemp=dtemp->right_siblings;
			}

	modify_fd(root,current,source,dest);		
	modify_fd_rec(root,current->left_child,source,dest);
	current->is_deleted = 1;
	return 0;
}

